package com.kh.rationaldrugreview.service;

import com.kh.rationaldrugreview.dto.*;
import com.kh.rationaldrugreview.enums.RiskFactor;
import com.kh.rationaldrugreview.enums.RiskLevel;
import com.kh.rationaldrugreview.neo4j.service.Neo4jCypherService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 风险评估引擎
 * Risk Assessment Engine
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class RiskAssessmentEngine {
    
    private final Neo4jCypherService neo4jCypherService;
    private final RiskCalculator riskCalculator;
    
    /**
     * 执行完整的风险评估
     */
    public PrescriptionRiskAssessmentResponse assess(PrescriptionRiskAssessmentRequest request) {
        long startTime = System.currentTimeMillis();
        String assessmentId = generateAssessmentId();
        
        try {
            // 1. 构建患者上下文
            PatientContext patientContext = buildPatientContext(request.getPatient());
            
            // 2. 获取评估选项
            PrescriptionRiskAssessmentRequest.AssessmentOptions options = request.getOptionsOrDefault();
            
            // 3. 并行执行各维度风险检查
            List<CompletableFuture<List<RiskItem>>> riskChecks = new ArrayList<>();
            
            if (options.getCheckInteractions()) {
                riskChecks.add(checkDrugInteractions(request.getDrugNames()));
            }
            
            if (options.getCheckPregnancy() && Boolean.TRUE.equals(patientContext.getIsPregnant())) {
                riskChecks.add(checkPregnancyRisks(request.getDrugNames(), patientContext));
            }
            
            if (options.getCheckContraindications()) {
                riskChecks.add(checkContraindications(request.getDrugNames(), patientContext));
            }
            
            if (options.getCheckOrganFunction()) {
                riskChecks.add(checkOrganFunctionRisks(request.getDrugNames(), patientContext));
            }
            
            if (options.getCheckAge()) {
                riskChecks.add(checkAgeRisks(request.getDrugNames(), patientContext));
            }
            
            if (options.getCheckAllergies()) {
                riskChecks.add(checkAllergyRisks(request.getDrugNames(), patientContext));
            }
            
            if (options.getCheckDuplication()) {
                riskChecks.add(checkDuplicationRisks(request.getDrugs()));
            }
            
            // 4. 等待所有检查完成
            CompletableFuture<Void> allChecks = CompletableFuture.allOf(
                riskChecks.toArray(new CompletableFuture[0]));
            
            List<RiskItem> allRisks = allChecks.thenApply(v -> 
                riskChecks.stream()
                    .flatMap(future -> future.join().stream())
                    .collect(Collectors.toList())
            ).join();
            
            // 5. 过滤风险项
            if (!options.getIncludeMinorRisks()) {
                allRisks = allRisks.stream()
                    .filter(risk -> risk.getRiskLevel() != RiskLevel.LOW)
                    .collect(Collectors.toList());
            }
            
            // 6. 计算综合风险等级
            RiskLevel overallRisk = riskCalculator.calculateOverallRisk(allRisks);
            
            // 7. 生成临床建议
            List<ClinicalRecommendation> recommendations = new ArrayList<>();
            if (options.getGenerateRecommendations()) {
                recommendations = generateRecommendations(allRisks, patientContext);
            }
            
            // 8. 排序风险项
            if (options.getPrioritizeByRisk()) {
                allRisks.sort((r1, r2) -> {
                    int levelCompare = Integer.compare(
                        r2.getRiskLevel().getLevel(), 
                        r1.getRiskLevel().getLevel()
                    );
                    if (levelCompare != 0) return levelCompare;
                    
                    // 相同级别按分值排序
                    Integer score1 = r1.getScore() != null ? r1.getScore() : 0;
                    Integer score2 = r2.getScore() != null ? r2.getScore() : 0;
                    return Integer.compare(score2, score1);
                });
            }
            
            // 9. 构建响应
            long processingTime = System.currentTimeMillis() - startTime;
            
            return PrescriptionRiskAssessmentResponse.builder()
                .assessmentId(assessmentId)
                .status(PrescriptionRiskAssessmentResponse.AssessmentStatus.SUCCESS)
                .overallRiskLevel(overallRisk)
                .riskScore(calculateTotalScore(allRisks))
                .summary(generateSummary(overallRisk, allRisks))
                .riskItems(allRisks)
                .recommendations(recommendations)
                .statistics(calculateStatistics(allRisks))
                .patientSummary(patientContext.getRiskProfileSummary())
                .prescriptionSummary(generatePrescriptionSummary(request))
                .assessmentTime(LocalDateTime.now())
                .processingTimeMs(processingTime)
                .dataSource("Knowledge Graph")
                .version("1.0")
                .build();
            
        } catch (Exception e) {
            log.error("Risk assessment failed for request: {}", request, e);
            return createErrorResponse(assessmentId, e.getMessage());
        }
    }
    
    /**
     * 构建患者上下文
     */
    private PatientContext buildPatientContext(PrescriptionRiskAssessmentRequest.PatientInfo patientInfo) {
        PatientContext context = PatientContext.builder()
            .patientId(patientInfo.getPatientId() != null ? Long.parseLong(patientInfo.getPatientId()) : null)
            .name(patientInfo.getName())
            .gender(patientInfo.getGender())
            .age(patientInfo.getAge())
            .weight(patientInfo.getWeight())
            .height(patientInfo.getHeight())
            .isPregnant(patientInfo.getIsPregnant())
            .pregnancyStatus(patientInfo.getPregnancyTrimester())
            .gestationalWeek(patientInfo.getGestationalWeek())
            .isLactating(patientInfo.getIsLactating())
            .renalFunction(patientInfo.getRenalFunction())
            .creatinineClearance(patientInfo.getCreatinineClearance())
            .hepaticFunction(patientInfo.getHepaticFunction())
            .medicalHistory(patientInfo.getMedicalHistory())
            .allergies(patientInfo.getAllergies())
            .currentMedications(patientInfo.getCurrentMedications())
            .smokingStatus(patientInfo.getSmokingStatus())
            .drinkingStatus(patientInfo.getDrinkingStatus())
            .hasDiabetes(patientInfo.getHasDiabetes())
            .hasHypertension(patientInfo.getHasHypertension())
            .hasHeartDisease(patientInfo.getHasHeartDisease())
            .build();
        
        // 计算BMI和体表面积
        context.calculateBMI();
        context.calculateBSA();
        
        // 确定年龄组
        if (context.getAge() != null) {
            context.setAgeGroup(determineAgeGroup(context.getAge()));
        }
        
        return context;
    }
    
    /**
     * 检查药物相互作用
     */
    private CompletableFuture<List<RiskItem>> checkDrugInteractions(List<String> drugNames) {
        return CompletableFuture.supplyAsync(() -> {
            try {
                List<Map<String, Object>> interactions = neo4jCypherService.findAllDrugInteractions(drugNames);
                List<RiskItem> riskItems = new ArrayList<>();
                
                for (Map<String, Object> interaction : interactions) {
                    String drug1 = (String) interaction.get("drug1");
                    String drug2 = (String) interaction.get("drug2");
                    String severity = (String) interaction.getOrDefault("severity", "mild");
                    String mechanism = (String) interaction.get("mechanism");
                    String management = (String) interaction.get("management");
                    Integer strength = (Integer) interaction.get("strength");
                    
                    RiskLevel riskLevel = mapSeverityToRiskLevel(severity);
                    RiskFactor riskFactor = mapSeverityToRiskFactor(severity);
                    
                    RiskItem riskItem = RiskItem.builder()
                        .riskId(UUID.randomUUID().toString())
                        .riskFactor(riskFactor)
                        .riskLevel(riskLevel)
                        .title("药物相互作用")
                        .description(String.format("%s 与 %s 存在相互作用", drug1, drug2))
                        .details(mechanism)
                        .affectedDrugs(Arrays.asList(drug1, drug2))
                        .interactingDrug(drug2)
                        .score(strength)
                        .recommendation(management)
                        .severity(severity)
                        .mechanism(mechanism)
                        .timestamp(System.currentTimeMillis())
                        .source("Knowledge Graph")
                        .overrideable(riskLevel != RiskLevel.CRITICAL)
                        .build();
                    
                    riskItems.add(riskItem);
                }
                
                log.debug("Found {} drug interactions", riskItems.size());
                return riskItems;
                
            } catch (Exception e) {
                log.error("Error checking drug interactions", e);
                return new ArrayList<>();
            }
        });
    }
    
    /**
     * 检查妊娠期风险
     */
    private CompletableFuture<List<RiskItem>> checkPregnancyRisks(List<String> drugNames, PatientContext patient) {
        return CompletableFuture.supplyAsync(() -> {
            try {
                List<Map<String, Object>> pregnancyData = neo4jCypherService.findPregnancyCategories(drugNames);
                List<RiskItem> riskItems = new ArrayList<>();
                
                for (Map<String, Object> data : pregnancyData) {
                    String drugName = (String) data.get("drugName");
                    String category = (String) data.get("category");
                    String fetalRisk = (String) data.get("fetalRisk");
                    String trimesterSpecific = (String) data.get("trimesterSpecific");
                    
                    RiskLevel riskLevel = riskCalculator.calculatePregnancyRisk(category, patient.getPregnancyStatus());
                    RiskFactor riskFactor = getPregnancyRiskFactor(category);
                    
                    if (riskLevel != RiskLevel.NONE) {
                        RiskItem riskItem = RiskItem.builder()
                            .riskId(UUID.randomUUID().toString())
                            .riskFactor(riskFactor)
                            .riskLevel(riskLevel)
                            .title("妊娠期用药风险")
                            .description(String.format("%s FDA妊娠分级为%s级", drugName, category))
                            .details(fetalRisk)
                            .affectedDrugs(List.of(drugName))
                            .score(riskFactor.getScore())
                            .recommendation(generatePregnancyRecommendation(category))
                            .severity(category)
                            .timestamp(System.currentTimeMillis())
                            .source("Knowledge Graph")
                            .overrideable(riskLevel != RiskLevel.CRITICAL)
                            .build();
                        
                        riskItems.add(riskItem);
                    }
                }
                
                log.debug("Found {} pregnancy risks", riskItems.size());
                return riskItems;
                
            } catch (Exception e) {
                log.error("Error checking pregnancy risks", e);
                return new ArrayList<>();
            }
        });
    }
    
    /**
     * 检查禁忌症
     */
    private CompletableFuture<List<RiskItem>> checkContraindications(List<String> drugNames, PatientContext patient) {
        return CompletableFuture.supplyAsync(() -> {
            try {
                List<String> patientConditions = buildPatientConditions(patient);
                List<Map<String, Object>> contraindications = 
                    neo4jCypherService.findContraindicationsForPatient(drugNames, patientConditions);
                List<RiskItem> riskItems = new ArrayList<>();
                
                for (Map<String, Object> contraindication : contraindications) {
                    String drugName = (String) contraindication.get("drugName");
                    String condition = (String) contraindication.get("condition");
                    String type = (String) contraindication.get("contraindicationType");
                    String reason = (String) contraindication.get("reason");
                    String alternative = (String) contraindication.get("alternative");
                    
                    RiskLevel riskLevel = "绝对禁忌".equals(type) ? RiskLevel.CRITICAL : RiskLevel.HIGH;
                    RiskFactor riskFactor = "绝对禁忌".equals(type) ? 
                        RiskFactor.ABSOLUTE_CONTRAINDICATION : RiskFactor.RELATIVE_CONTRAINDICATION;
                    
                    RiskItem riskItem = RiskItem.builder()
                        .riskId(UUID.randomUUID().toString())
                        .riskFactor(riskFactor)
                        .riskLevel(riskLevel)
                        .title("禁忌症")
                        .description(String.format("患者存在%s的禁忌症：%s", drugName, condition))
                        .details(reason)
                        .affectedDrugs(List.of(drugName))
                        .score(riskFactor.getScore())
                        .recommendation("绝对禁忌".equals(type) ? "禁止使用" : "权衡利弊后谨慎使用")
                        .alternatives(alternative != null ? List.of(alternative) : new ArrayList<>())
                        .severity(type)
                        .timestamp(System.currentTimeMillis())
                        .source("Knowledge Graph")
                        .overrideable(riskLevel != RiskLevel.CRITICAL)
                        .build();
                    
                    riskItems.add(riskItem);
                }
                
                log.debug("Found {} contraindications", riskItems.size());
                return riskItems;
                
            } catch (Exception e) {
                log.error("Error checking contraindications", e);
                return new ArrayList<>();
            }
        });
    }
    
    /**
     * 检查器官功能风险
     */
    private CompletableFuture<List<RiskItem>> checkOrganFunctionRisks(List<String> drugNames, PatientContext patient) {
        return CompletableFuture.supplyAsync(() -> {
            try {
                List<Map<String, Object>> requirements = 
                    neo4jCypherService.findOrganFunctionRequirements(drugNames, null);
                List<RiskItem> riskItems = new ArrayList<>();
                
                for (Map<String, Object> requirement : requirements) {
                    String drugName = (String) requirement.get("drugName");
                    String organName = (String) requirement.get("organName");
                    String requiredLevel = (String) requirement.get("requiredLevel");
                    String dosageAdjustment = (String) requirement.get("dosageAdjustment");
                    String monitoring = (String) requirement.get("monitoringFrequency");
                    
                    String patientFunction = getPatientOrganFunction(patient, organName);
                    RiskLevel riskLevel = riskCalculator.calculateOrganFunctionRisk(patientFunction, requiredLevel);
                    
                    if (riskLevel != RiskLevel.NONE) {
                        RiskFactor riskFactor = getOrganFunctionRiskFactor(organName, patientFunction);
                        
                        RiskItem riskItem = RiskItem.builder()
                            .riskId(UUID.randomUUID().toString())
                            .riskFactor(riskFactor)
                            .riskLevel(riskLevel)
                            .title("器官功能风险")
                            .description(String.format("患者%s功能(%s)可能影响%s的使用", 
                                organName, patientFunction, drugName))
                            .details(String.format("要求%s功能达到%s", organName, requiredLevel))
                            .affectedDrugs(List.of(drugName))
                            .score(riskFactor.getScore())
                            .recommendation(dosageAdjustment != null ? dosageAdjustment : "需要调整剂量")
                            .dosageAdjustment(dosageAdjustment)
                            .monitoringParameters(monitoring != null ? List.of(monitoring) : new ArrayList<>())
                            .timestamp(System.currentTimeMillis())
                            .source("Knowledge Graph")
                            .overrideable(true)
                            .build();
                        
                        riskItems.add(riskItem);
                    }
                }
                
                log.debug("Found {} organ function risks", riskItems.size());
                return riskItems;
                
            } catch (Exception e) {
                log.error("Error checking organ function risks", e);
                return new ArrayList<>();
            }
        });
    }
    
    /**
     * 检查年龄风险
     */
    private CompletableFuture<List<RiskItem>> checkAgeRisks(List<String> drugNames, PatientContext patient) {
        return CompletableFuture.supplyAsync(() -> {
            try {
                if (patient.getAge() == null) return new ArrayList<>();
                
                List<Map<String, Object>> ageCompatibility = 
                    neo4jCypherService.findAgeGroupCompatibility(drugNames, patient.getAgeGroup());
                List<RiskItem> riskItems = new ArrayList<>();
                
                // 检查年龄适用性
                for (String drugName : drugNames) {
                    boolean found = ageCompatibility.stream()
                        .anyMatch(data -> drugName.equals(data.get("drugName")));
                    
                    if (!found) {
                        // 该药物可能不适合此年龄组
                        RiskLevel riskLevel = determineAgeRiskLevel(patient);
                        RiskFactor riskFactor = determineAgeRiskFactor(patient);
                        
                        if (riskLevel != RiskLevel.NONE) {
                            RiskItem riskItem = RiskItem.builder()
                                .riskId(UUID.randomUUID().toString())
                                .riskFactor(riskFactor)
                                .riskLevel(riskLevel)
                                .title("年龄限制")
                                .description(String.format("%s在%s患者中的使用需要特别注意", 
                                    drugName, patient.getAgeGroup()))
                                .affectedDrugs(List.of(drugName))
                                .score(riskFactor.getScore())
                                .recommendation(generateAgeRecommendation(patient.getAgeGroup()))
                                .timestamp(System.currentTimeMillis())
                                .source("Knowledge Graph")
                                .overrideable(true)
                                .build();
                            
                            riskItems.add(riskItem);
                        }
                    }
                }
                
                log.debug("Found {} age risks", riskItems.size());
                return riskItems;
                
            } catch (Exception e) {
                log.error("Error checking age risks", e);
                return new ArrayList<>();
            }
        });
    }
    
    /**
     * 检查过敏风险
     */
    private CompletableFuture<List<RiskItem>> checkAllergyRisks(List<String> drugNames, PatientContext patient) {
        return CompletableFuture.supplyAsync(() -> {
            List<RiskItem> riskItems = new ArrayList<>();
            
            if (patient.getAllergies() == null || patient.getAllergies().isEmpty()) {
                return riskItems;
            }
            
            // 简化的过敏检查逻辑
            for (String drugName : drugNames) {
                for (String allergy : patient.getAllergies()) {
                    if (drugName.toLowerCase().contains(allergy.toLowerCase()) || 
                        allergy.toLowerCase().contains(drugName.toLowerCase())) {
                        
                        RiskItem riskItem = RiskItem.builder()
                            .riskId(UUID.randomUUID().toString())
                            .riskFactor(RiskFactor.ALLERGY_RISK)
                            .riskLevel(RiskLevel.HIGH)
                            .title("过敏风险")
                            .description(String.format("患者对%s存在过敏史", drugName))
                            .details(String.format("过敏史：%s", allergy))
                            .affectedDrugs(List.of(drugName))
                            .score(RiskFactor.ALLERGY_RISK.getScore())
                            .recommendation("禁止使用，寻找替代药物")
                            .timestamp(System.currentTimeMillis())
                            .source("Patient History")
                            .overrideable(false)
                            .build();
                        
                        riskItems.add(riskItem);
                    }
                }
            }
            
            log.debug("Found {} allergy risks", riskItems.size());
            return riskItems;
        });
    }
    
    /**
     * 检查重复用药风险
     */
    private CompletableFuture<List<RiskItem>> checkDuplicationRisks(
            List<PrescriptionRiskAssessmentRequest.PrescriptionDrug> drugs) {
        return CompletableFuture.supplyAsync(() -> {
            List<RiskItem> riskItems = new ArrayList<>();
            
            // 按活性成分分组
            Map<String, List<PrescriptionRiskAssessmentRequest.PrescriptionDrug>> ingredientGroups = 
                drugs.stream()
                    .filter(drug -> drug.getActiveIngredient() != null)
                    .collect(Collectors.groupingBy(
                        PrescriptionRiskAssessmentRequest.PrescriptionDrug::getActiveIngredient
                    ));
            
            // 检查重复用药
            for (Map.Entry<String, List<PrescriptionRiskAssessmentRequest.PrescriptionDrug>> entry : 
                 ingredientGroups.entrySet()) {
                if (entry.getValue().size() > 1) {
                    List<String> drugNames = entry.getValue().stream()
                        .map(PrescriptionRiskAssessmentRequest.PrescriptionDrug::getDrugName)
                        .collect(Collectors.toList());
                    
                    RiskItem riskItem = RiskItem.builder()
                        .riskId(UUID.randomUUID().toString())
                        .riskFactor(RiskFactor.DUPLICATE_THERAPY)
                        .riskLevel(RiskLevel.MEDIUM)
                        .title("重复用药")
                        .description(String.format("存在相同活性成分的药物：%s", entry.getKey()))
                        .details(String.format("涉及药物：%s", String.join("、", drugNames)))
                        .affectedDrugs(drugNames)
                        .score(RiskFactor.DUPLICATE_THERAPY.getScore())
                        .recommendation("确认是否需要同时使用这些药物")
                        .timestamp(System.currentTimeMillis())
                        .source("Prescription Analysis")
                        .overrideable(true)
                        .build();
                    
                    riskItems.add(riskItem);
                }
            }
            
            log.debug("Found {} duplication risks", riskItems.size());
            return riskItems;
        });
    }
    
    // 辅助方法
    private String generateAssessmentId() {
        return "RISK_" + System.currentTimeMillis() + "_" + UUID.randomUUID().toString().substring(0, 8);
    }
    
    private String determineAgeGroup(Integer age) {
        if (age < 1) return "新生儿";
        if (age < 3) return "幼儿";
        if (age < 12) return "儿童";
        if (age < 18) return "青少年";
        if (age < 65) return "成人";
        return "老年人";
    }
    
    private RiskLevel mapSeverityToRiskLevel(String severity) {
        return switch (severity.toLowerCase()) {
            case "severe", "major" -> RiskLevel.HIGH;
            case "moderate" -> RiskLevel.MEDIUM;
            case "mild", "minor" -> RiskLevel.LOW;
            default -> RiskLevel.NONE;
        };
    }
    
    private RiskFactor mapSeverityToRiskFactor(String severity) {
        return switch (severity.toLowerCase()) {
            case "severe", "major" -> RiskFactor.SEVERE_INTERACTION;
            case "moderate" -> RiskFactor.MODERATE_INTERACTION;
            case "mild", "minor" -> RiskFactor.MILD_INTERACTION;
            default -> RiskFactor.MILD_INTERACTION;
        };
    }
    
    private RiskFactor getPregnancyRiskFactor(String category) {
        return switch (category.toUpperCase()) {
            case "X" -> RiskFactor.PREGNANCY_CATEGORY_X;
            case "D" -> RiskFactor.PREGNANCY_CATEGORY_D;
            case "C" -> RiskFactor.PREGNANCY_CATEGORY_C;
            case "B" -> RiskFactor.PREGNANCY_CATEGORY_B;
            case "A" -> RiskFactor.PREGNANCY_CATEGORY_A;
            default -> RiskFactor.PREGNANCY_CATEGORY_C;
        };
    }
    
    private String generatePregnancyRecommendation(String category) {
        return switch (category.toUpperCase()) {
            case "X" -> "绝对禁用于孕妇";
            case "D" -> "仅在获益明显超过风险时使用";
            case "C" -> "权衡利弊后谨慎使用";
            case "B" -> "相对安全，可在医生指导下使用";
            case "A" -> "孕期使用安全";
            default -> "需要评估孕期使用的安全性";
        };
    }
    
    private List<String> buildPatientConditions(PatientContext patient) {
        List<String> conditions = new ArrayList<>();
        
        if (patient.getMedicalHistory() != null) {
            conditions.addAll(patient.getMedicalHistory());
        }
        
        if (Boolean.TRUE.equals(patient.getIsPregnant())) {
            conditions.add("妊娠");
        }
        
        if (Boolean.TRUE.equals(patient.getIsLactating())) {
            conditions.add("哺乳期");
        }
        
        if (patient.hasRenalImpairment()) {
            conditions.add("肾功能不全");
        }
        
        if (patient.hasHepaticImpairment()) {
            conditions.add("肝功能不全");
        }
        
        return conditions;
    }
    
    private String getPatientOrganFunction(PatientContext patient, String organName) {
        return switch (organName) {
            case "肾", "kidney" -> patient.getRenalFunction();
            case "肝", "liver" -> patient.getHepaticFunction();
            default -> "正常";
        };
    }
    
    private RiskFactor getOrganFunctionRiskFactor(String organName, String functionLevel) {
        if ("肾".equals(organName) || "kidney".equals(organName)) {
            return switch (functionLevel) {
                case "重度不全" -> RiskFactor.RENAL_SEVERE_IMPAIRMENT;
                case "中度不全" -> RiskFactor.RENAL_MODERATE_IMPAIRMENT;
                case "轻度不全" -> RiskFactor.RENAL_MILD_IMPAIRMENT;
                default -> RiskFactor.REQUIRES_MONITORING;
            };
        } else if ("肝".equals(organName) || "liver".equals(organName)) {
            return switch (functionLevel) {
                case "重度不全" -> RiskFactor.HEPATIC_SEVERE_IMPAIRMENT;
                case "中度不全" -> RiskFactor.HEPATIC_MODERATE_IMPAIRMENT;
                case "轻度不全" -> RiskFactor.HEPATIC_MILD_IMPAIRMENT;
                default -> RiskFactor.REQUIRES_MONITORING;
            };
        }
        return RiskFactor.REQUIRES_MONITORING;
    }
    
    private RiskLevel determineAgeRiskLevel(PatientContext patient) {
        if (patient.isPediatric() || patient.isGeriatric()) {
            return RiskLevel.MEDIUM;
        }
        return RiskLevel.LOW;
    }
    
    private RiskFactor determineAgeRiskFactor(PatientContext patient) {
        if (patient.isPediatric()) {
            return RiskFactor.PEDIATRIC_CONCERN;
        } else if (patient.isGeriatric()) {
            return RiskFactor.GERIATRIC_CONCERN;
        }
        return RiskFactor.AGE_RESTRICTION;
    }
    
    private String generateAgeRecommendation(String ageGroup) {
        return switch (ageGroup) {
            case "新生儿", "幼儿" -> "儿童用药需要特别注意剂量和安全性";
            case "老年人" -> "老年患者可能需要调整剂量，注意不良反应";
            default -> "需要确认该年龄组的用药安全性";
        };
    }
    
    private List<ClinicalRecommendation> generateRecommendations(List<RiskItem> risks, PatientContext patient) {
        // 这里可以实现更复杂的建议生成逻辑
        // 为了简化，返回基于风险项的基本建议
        return risks.stream()
            .filter(risk -> risk.getRiskLevel().isHighRisk())
            .map(this::convertRiskToRecommendation)
            .collect(Collectors.toList());
    }
    
    private ClinicalRecommendation convertRiskToRecommendation(RiskItem risk) {
        return ClinicalRecommendation.builder()
            .recommendationId(UUID.randomUUID().toString())
            .type(determineRecommendationType(risk))
            .priority(risk.getRiskLevel())
            .title(risk.getTitle())
            .content(risk.getRecommendation())
            .affectedDrugs(risk.getAffectedDrugs())
            .rationale(risk.getDescription())
            .mandatory(risk.getRiskLevel() == RiskLevel.CRITICAL)
            .build();
    }
    
    private ClinicalRecommendation.RecommendationType determineRecommendationType(RiskItem risk) {
        if (risk.getRiskLevel() == RiskLevel.CRITICAL) {
            return ClinicalRecommendation.RecommendationType.STOP_MEDICATION;
        } else if (risk.getAlternatives() != null && !risk.getAlternatives().isEmpty()) {
            return ClinicalRecommendation.RecommendationType.REPLACE_MEDICATION;
        } else if (risk.getDosageAdjustment() != null) {
            return ClinicalRecommendation.RecommendationType.ADJUST_DOSE;
        } else {
            return ClinicalRecommendation.RecommendationType.ADD_MONITORING;
        }
    }
    
    private Integer calculateTotalScore(List<RiskItem> risks) {
        return risks.stream()
            .mapToInt(risk -> risk.getScore() != null ? risk.getScore() : 0)
            .sum();
    }
    
    private String generateSummary(RiskLevel overallRisk, List<RiskItem> risks) {
        return String.format("综合风险等级：%s，共发现 %d 项风险", 
            overallRisk.getChineseName(), risks.size());
    }
    
    private String generatePrescriptionSummary(PrescriptionRiskAssessmentRequest request) {
        return String.format("处方包含 %d 种药物，患者：%s", 
            request.getDrugs().size(), request.getPatientRiskSummary());
    }
    
    private PrescriptionRiskAssessmentResponse.RiskStatistics calculateStatistics(List<RiskItem> risks) {
        Map<RiskLevel, Long> riskCounts = risks.stream()
            .collect(Collectors.groupingBy(RiskItem::getRiskLevel, Collectors.counting()));
        
        return PrescriptionRiskAssessmentResponse.RiskStatistics.builder()
            .totalRisks(risks.size())
            .criticalRisks(riskCounts.getOrDefault(RiskLevel.CRITICAL, 0L).intValue())
            .highRisks(riskCounts.getOrDefault(RiskLevel.HIGH, 0L).intValue())
            .mediumRisks(riskCounts.getOrDefault(RiskLevel.MEDIUM, 0L).intValue())
            .lowRisks(riskCounts.getOrDefault(RiskLevel.LOW, 0L).intValue())
            .hasHighPriorityRisks(riskCounts.getOrDefault(RiskLevel.CRITICAL, 0L) > 0 ||
                                 riskCounts.getOrDefault(RiskLevel.HIGH, 0L) > 0)
            .requiresImmediateAction(riskCounts.getOrDefault(RiskLevel.CRITICAL, 0L) > 0)
            .build();
    }
    
    private PrescriptionRiskAssessmentResponse createErrorResponse(String assessmentId, String errorMessage) {
        return PrescriptionRiskAssessmentResponse.builder()
            .assessmentId(assessmentId)
            .status(PrescriptionRiskAssessmentResponse.AssessmentStatus.ERROR)
            .overallRiskLevel(RiskLevel.NONE)
            .summary("风险评估失败：" + errorMessage)
            .riskItems(new ArrayList<>())
            .recommendations(new ArrayList<>())
            .assessmentTime(LocalDateTime.now())
            .build();
    }
}